package fr.ul.ade.prime.ui;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.NavUtils;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.SimpleOnPageChangeListener;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.MenuItem;

import fr.ul.ade.R;
import fr.ul.ade.prime.model.AdeWebOptions;
import fr.ul.ade.prime.model.Lesson;
import fr.ul.ade.prime.model.LessonHistory;
import fr.ul.ade.prime.model.LessonType;
import fr.ul.ade.prime.model.Preferences;
import fr.ul.ade.prime.provider.AdeWebContract;
import fr.ul.ade.prime.ui.LessonList.LessonBundle;

/**
 * Vue affichant les informations d'un cours (détail d'un cours).
 * 
 * @author Zanette Sébastien
 */
public class LessonDetails extends AdeWebFragmentActivity implements
		BundleExtraNames, Preferences {

	@SuppressWarnings("hiding")
	protected static final String TAG = LessonDetails.class.getSimpleName();

	protected static final String FRAGMENT_ARG_LESSON = "lesson"; //$NON-NLS-1$

	/**
	 * Nom du cours courant dans la liste de cours.
	 */
	protected String nameLesson;
	/**
	 * Index du cours courant dans la liste de cours.
	 */
	protected long idLesson;
	/**
	 * Liste complète des id des cours de l'emploi du temps.
	 */
	protected ArrayList<LessonBundle> lessons;
	/**
	 * Boite de dialogue affichant un chargement lorsqu'un emploi du temps est
	 * mis à jour.
	 */
	// protected ProgressDialog updateDialog;

	protected MyAdapter mAdapter;

	protected ViewPager mPager;

	// protected static Handler handler = new Handler() {
	// @Override
	// public void handleMessage(Message msg) {
	// if (msg.what == REMOVE_LESSON_HISTORY) {
	// UpdateMessageContent content = (UpdateMessageContent) msg.obj ;
	// // Log.d(TAG,
	// String.format("-- content.service: %s - content.lessonId: %s",
	// // content.getServiceApi(), content.getLessonId())) ;
	// try {
	// content.getServiceApi().removeLessonHistory(
	// content.getLessonId()) ;
	// } catch (RemoteException re) {
	// Log.d(TAG, String.format(
	//							"Failed to remove history for lesson %d", //$NON-NLS-1$
	// Long.valueOf(content.getLessonId())), re) ;
	// }// try
	// } else {
	// super.handleMessage(msg) ;
	// }
	// }
	// } ;

	/**
	 * Initialise la vue.
	 * 
	 * @param savedInstanceState
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Fixe le thème de la page
		this.setTheme(AdeWebOptions.getThemeAde(this));
		// Ajoute une petite flèche à gauche du logo dans la barre d'action
		getSupportActionBar().setDisplayHomeAsUpEnabled(true);

		setContentView(R.layout.lesson_details);

		// Recupére la liste compléte des cours de l'emploi du temps passé en
		// paramètre
		// Récupère les Bundle passés en parametre cet Intent
		ArrayList<LessonBundle> lessonsBundle = this.getIntent()
				.getParcelableArrayListExtra(EXTRA_SCHEDULE_LESSONS);
		long idCurantLesson = this.getIntent()
				.getLongExtra(EXTRA_DISPLAYED_LESSON, 0);
		String nameSchedule = this.getIntent()
				.getStringExtra(EXTRA_SCHEDULE_NAME);
		this.nameLesson = this.getIntent().getStringExtra(EXTRA_LESSON_NAME);

		// Positionne l'indice du cours courant
		this.idLesson = idCurantLesson;
		// Positionne la liste des cours de l'edt
		this.lessons = lessonsBundle;

		// Fixe le sous-titre de la barre d'action
		this.getSupportActionBar().setTitle(this.nameLesson);
		this.getSupportActionBar().setSubtitle(nameSchedule);

		this.mAdapter = new MyAdapter(getSupportFragmentManager(), this.lessons);
		this.mPager = (ViewPager) findViewById(R.id.lesson_details_viewpager);
		this.mPager.setAdapter(this.mAdapter);
		this.mPager.setOnPageChangeListener(new myPageChangeListener());
		this.mPager.setPageMarginDrawable(R.drawable.grey_border_inset_lr);
		this.mPager.setPageMargin(getResources()
				.getDimensionPixelSize(R.dimen.page_margin_width));

		// Positionne le viewPager à la bonne page
		this.mPager.setCurrentItem(this.getPositionWithID(this.idLesson));
	}// onCreate(Bundle)

	/**
	 * Récupère l'index de {@LessonBundle} avec l'id passé en
	 * paramètre.
	 * 
	 * @param id
	 *            id du cours
	 * @return l'index de {@LessonBundle} dans la liste
	 */
	public int getPositionWithID(long id) {
		return this.lessons.indexOf(new LessonBundle(id));
	}

	/**
	 * Récupère l'id de {@LessonBundle} avec la position dans la
	 * liste passé en paramètre.
	 * 
	 * @param index
	 *            position de {@LessonBundle} dans la liste
	 * @return id du cours
	 */
	public long getIDWithPosition(int index) {
		return this.lessons.get(index).lessonId;
	}

	// /**
	// * {@inheritDoc}
	// * @see
	// fr.ul.ade.prime.ui.AdeWebFragmentActivity#getAdeWebServiceListener()
	// */
	// @Override
	// protected AdeWebServiceListener getAdeWebServiceListener() {
	// return new AdeWebServiceListenerAdapter(this) ;
	// }// getAdeWebServiceListener()
	//
	// /**
	// * Remet à zéro après consultation du changement
	// */
	// /*private void remisAZero(){
	// Database db = new Database();
	// db.updateStatutLesson(this.lesson.getLessonId(),
	// this.lesson.getSchedule(), Lesson.NO_CHANGE);
	// db.removeLesson_HistoryWithID(lesson.getLessonId(),
	// lesson.getSchedule());
	// }*/
	//
	// /**
	// * Affiche les boutons/options de la barre d'action.
	// */
	// @Override
	// public boolean onCreateOptionsMenu(Menu menu) {
	// menu.add(R.string.ActionBar_mark)
	// .setIcon(R.drawable.ic_action_edit_holo_dark)
	// .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
	// MenuItem.SHOW_AS_ACTION_WITH_TEXT);
	// return super.onCreateOptionsMenu(menu);
	// }

	/**
	 * Gére les actions des boutons/options de la barre d'action.
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			Bundle extras = this.getIntent().getExtras();
			Intent intent = NavUtils.getParentActivityIntent(this);
			intent.putExtra(EXTRA_SCHEDULE_ID,
					extras.getLong(EXTRA_SCHEDULE_ID));
			intent.putExtra(EXTRA_SCHEDULE_NAME,
					extras.getString(EXTRA_SCHEDULE_NAME));
			intent.putExtra(EXTRA_SCHEDULE_PERIOD,
					extras.getInt(EXTRA_SCHEDULE_PERIOD));
			NavUtils.navigateUpTo(this, intent);
			return true;
		default /* android.R.id.home */:
			NavUtils.navigateUpFromSameTask(this);
		}// switch
		return true;
	}

	// /**
	// * Affiche une boite de dialogue avec les choix de type de cours. Normal,
	// * Inmportant, Examen.
	// */
	// private void mark() {
	// LessonType currentType = this.lesson.getType() ;
	//
	// AlertDialog.Builder builder = new Builder(this) ;
	// ListAdapter dialogAdapter = new ArrayAdapter<LessonType>(
	// this, android.R.layout.select_dialog_singlechoice, LessonType.values()) ;
	// builder.setSingleChoiceItems(dialogAdapter, currentType.ordinal(),
	// new MarkListener(this)) ;
	// builder.setTitle(R.string.ViewSchedule_mark_dialog_title) ;
	// builder.setIcon(RESULT_OK) ;
	// builder.create().show() ;
	// }// mark()
	//
	// /**
	// * Lorsqu'il y a eu un changement important dans, on récupére l'historique
	// deu cours, et on met le flag 'changement' à vrai
	// */
	// /* private void montrerChangement() {
	// Database db = new Database();
	// this.oldS = db.getLessonHistoryWithID(this.lesson.getLessonId(),
	// this.lesson.getSchedule());
	// this.changement = true;
	// }*/
	//
	// /**
	// * OnClickListener pour le marquage d'un cour.
	// *
	// * <p>Récupère le type du cours ans met à jour la base de données.
	// *
	// * @author Schnell Michaël, Zanette Sébastien
	// */
	// class MarkListener implements DialogInterface.OnClickListener {
	//
	// /**
	// * Vue contenant le composant attaché à l'écouteur.
	// */
	// private LessonDetails activity;
	//
	// /**
	// * Constructeur.
	// *
	// * @param activity View containing the component attached to this
	// * listener
	// */
	// public MarkListener(LessonDetails activity) {
	// super();
	// this.activity = activity;
	// }// MarkListener(LessonDetails)
	//
	// /**
	// * Définition des action du clique sur le composant attaché.
	// *
	// * @param actualView view of the component who has received a click
	// * event
	// */
	// /* public void onClick(DialogInterface dialog, LessonType item) {
	// Lesson dispLesson = this.container.getLesson();
	// // A new type has been selected
	// if (item != dispLesson.getType()) {
	// dispLesson.setType(item);
	// Database db = new Database();
	// db.updateLesson(dispLesson.getLessonId(), dispLesson.getSchedule(),
	// dispLesson);
	// this.container.init();
	// }// if
	// dialog.dismiss();
	// }// onClick(View)*/
	//
	// @Override
	// public void onClick(DialogInterface dialog, int which) {
	// LessonType[] lessonTypes = LessonType.values() ;
	// LessonType newType = lessonTypes[which] ;
	// if (!newType.equals(this.activity.lesson.getType())) {
	// try {
	// this.activity.serviceApi.setLessonType(
	// this.activity.lesson, newType) ;
	// } catch (RemoteException re) {
	//					Log.d(TAG, String.format("Failed to mark lesson '%s' (%s)",  //$NON-NLS-1$
	// this.activity.lesson.getTitle(),
	// Long.valueOf(this.activity.lesson.getLessonId())), re) ;
	// }// try
	// }// if
	//
	// dialog.dismiss() ;
	// }// onClick(DialogInterface, int)
	// }// class MarkListener
	//
	// // /**
	// // * Retourne une instance de {@code Lesson} contenant l'information sur
	// la
	// // * lesson à afficher.
	// // */
	// // private Lesson getIntentLesson() {
	// // long id = this.getIntent().getLongExtra(EXTRA_DISPLAYED_LESSON,0);
	// // return this.lessons.get((int)id);
	// // }// getIntentLesson()
	//
	// /**
	// * Retourne une instance de {@code Lessons} contenant tous les cours de
	// l'emploi du temps.
	// */
	// private Lessons getIntentLessons() {
	// return this.getIntent().getParcelableExtra(EXTRA_SCHEDULE_LESSONS);
	// }// getIntentLesson()
	//
	// /**
	// * Retourne une instance de {@code Lesson} contenant l'information sur la
	// * lesson à afficher.
	// *
	// * @return instance of {@code Lesson} containing the information about the
	// * displayed lesson
	// */
	// public Lesson getLesson() {
	// return this.lesson;
	// }// getLesson()
	//
	//
	// /**
	// * Parse un {@code String} formaté de groupes et retourne une liste
	// * contenant tous les groupes.
	// *
	// * @param groups formatted {@code String} of groups
	// *
	// * @return Array containing all the groups
	// */
	// public static String[] parseGroups(String groups) {
	//		String[] g = groups.split(","); //$NON-NLS-1$
	//		if(g.length == 1 && g[0].equals("")){ //$NON-NLS-1$
	// g = new String[0];
	// }
	// return g;
	// }// parseGroup(String)
	//
	// /**
	// * Parse un {@code String} formaté d'enseignant et retourne une liste
	// * contenant tous les enseignants.
	// *
	// * @param teachers chaine de caractères d'enseignant séparés par des
	// virgules
	// * @return Array containing all the teachers
	// */
	// public static String[] parseTeachers(String teachers) {
	//		String[] g = teachers.split(","); //$NON-NLS-1$
	// if (g.length == 1 && TextUtils.isEmpty(g[0])){
	// g = new String[0];
	// }
	// return g;
	// }// parseTeachers(String)
	//
	// protected void sendUpdateMessage() {
	// LessonDetails.handler.removeMessages(REMOVE_LESSON_HISTORY) ;
	// if (this.lesson.getHistory() != null) {
	// Message msg = LessonDetails.handler.obtainMessage(
	// REMOVE_LESSON_HISTORY, new UpdateMessageContent(
	// this.serviceApi, this.lesson.getLessonId())) ;
	// LessonDetails.handler.sendMessageDelayed(msg,
	// REMOVE_LESSON_HISTORY_DELAY) ;
	// }
	// }
	//
	// /**
	// * OnCancelListener pour le bouton "annuler", si l'utilisateur souhaite
	// * quitter cette vue pendant que l'emploi du temps est synchronisé.
	// *
	// * @author Schnell Michaël, Zanette Sébastien
	// */
	// class UpdateCancelListener extends Object implements OnCancelListener {
	//
	// /**
	// * Vue contenant le composant attaché à l'écouteur.
	// */
	// protected LessonDetails container;
	//
	// /**
	// * Constructeur.
	// *
	// * @param container View containing the component attached to this
	// * listener
	// */
	// public UpdateCancelListener(LessonDetails container) {
	// super();
	// this.container = container;
	// }// UpdateCancelListener(LessonScreen)
	//
	// /**
	// * Définition l'action annuler.
	// *
	// * @param actualView view of the component who has received a click
	// * event
	// */
	// @Override
	// public void onCancel(DialogInterface dialog) {
	// dialog.dismiss();
	// this.container.onBackPressed();
	// }// onCancel(DialogInterface)
	// }// class UpdateCancelListener

	/**
	 * Adapter de {@code LessonFragment}.
	 * 
	 * @author Seb
	 * 
	 */
	public static class MyAdapter extends FragmentStatePagerAdapter {

		private ArrayList<LessonBundle> lessons;

		public MyAdapter(FragmentManager fm, ArrayList<LessonBundle> lessons) {
			super(fm);
			this.lessons = lessons;
		}

		@Override
		public int getCount() {
			return this.lessons.size();
		}

		@Override
		public Fragment getItem(int position) {
			return LessonFragment.newInstance(this.lessons.get(position));
		}
	}

	/**
	 * Fragment de vue d'un cours.
	 * 
	 * @author Seb
	 * 
	 */
	public static class LessonFragment extends SherlockFragment implements
			LoaderManager.LoaderCallbacks<Cursor> {
		LessonBundle lesson;
		ViewGroup mRootView;
		public static final String DATE_FORMAT = "EEE dd MMM"; //$NON-NLS-1$

		/**
		 * Create a new instance of ArrayListFragment, providing "num" as an
		 * argument.
		 */
		static LessonFragment newInstance(LessonBundle lesson) {
			LessonFragment f = new LessonFragment();

			// Supply num input as an argument.
			Bundle args = new Bundle();
			args.putParcelable(FRAGMENT_ARG_LESSON, lesson);
			f.setArguments(args);

			return f;
		}

		/**
		 * Ajout des données du cours dans le Layout.
		 * 
		 * @param view
		 * @param context
		 * @param cursor
		 */
		@SuppressLint("ParserError")
		public void bindView(View view, Context context, Cursor cursor) {
			final LayoutInflater inflater = this.getActivity()
					.getLayoutInflater();

			// On récupére les valeurs du cours courant
			Lesson displayedLesson = new Lesson(
					cursor.getString(LessonQuery.LESSON_TITLE),
					cursor.getString(LessonQuery.LESSON_DATE),
					cursor.getString(LessonQuery.LESSON_START_TIME),
					cursor.getString(LessonQuery.LESSON_END_TIME),
					cursor.getInt(LessonQuery.LESSON_SCHEDULE),
					LessonType.values()[cursor.getInt(LessonQuery.LESSON_TYPE)],
					cursor.getInt(LessonQuery.LESSON_CHANGE), cursor
							.getString(LessonQuery.LESSON_ROOMS), cursor
							.getString(LessonQuery.LESSON_GROUPS), cursor
							.getString(LessonQuery.LESSON_TEACHERS), cursor
							.getString(LessonQuery.LESSON_COLOR), cursor
							.getString(LessonQuery.LESSON_NOTE), cursor
							.getString(LessonQuery.LESSON_CREATED));

			// TODO Fixer le titre uniquement pour le fragement courant
			LessonDetails activity = ((LessonDetails) this.getActivity());
			activity.nameLesson = displayedLesson.getTitle();

			// Construction de l'historique du cours
			LessonHistory history = new LessonHistory(this.lesson.lessonId,
					cursor.getString(LessonQuery.LESSON_HISTORY_ROOMS),
					cursor.getString(LessonQuery.LESSON_HISTORY_DATE),
					cursor.getString(LessonQuery.LESSON_HISTORY_START_TIME),
					cursor.getString(LessonQuery.LESSON_HISTORY_END_TIME));

			// Récupére les préférences de l'utilisateur
			boolean useColor = AdeWebOptions.useAdeWebColors(context);

			// On teste s'il faut afficher des changements importants dans la
			// date ou les salles
			// TODO Gérer l'absence de salle
			String newRoom = displayedLesson.getRoom();
			if (TextUtils.isEmpty(newRoom)) {
				newRoom = this.getActivity().getResources()
						.getString(R.string.Lesson_room_unknown);
			}// if

			String oldroom = ""; //$NON-NLS-1$
			if (history.getRooms() != null) {
				oldroom = history.getRooms();
			} else {
				oldroom = newRoom;
			}// if

			// On initilise le header
			if (useColor) {
				LinearLayout layoutHeader = (LinearLayout) this.mRootView
						.findViewById(R.id.header_lesson);
				layoutHeader.setBackgroundColor(Color
						.parseColor(displayedLesson.getColor()));
			}// if
			TextView titleHeader = (TextView) this.mRootView
					.findViewById(R.id.lesson_title);
			TextView subtitleHeader = (TextView) this.mRootView
					.findViewById(R.id.lesson_subtitle);
			titleHeader.setText(displayedLesson.getTitle());
			// TODO Remove hard coded message
			subtitleHeader.setText(String.format("%s de %s à %s", //$NON-NLS-1$
					LessonFragment.displayDate(displayedLesson.getDate()),
					LessonFragment.displayTime(displayedLesson.getStartHour()),
					LessonFragment.displayTime(displayedLesson.getEndHour())));

			// On ajoute la date à laquelle était prévu le cours initiallement
			// (la section apparait uniquement si le cours a été déplacé et
			// affiche l'ancienne date)
			this.addInitialDateItem(displayedLesson.getDate(), history.getDate(),
					history.getStartHour(),
					history.getEndHour());

			// On ajoute les salles
			this.initRooms(inflater, newRoom, oldroom);

			// On ajoute les enseignants
			if (displayedLesson.getTeacher().length() != 0) {
				for (String teacher : LessonFragment.parseItems(displayedLesson
						.getTeacher())) {
					this.addTeacherItem(inflater, teacher);
				}// for
			} else {
				String noTeacherText = context.getResources()
						.getString(R.string.Lesson_teacher_unknown);
				this.addTeacherItem(inflater, noTeacherText);
			}// if

			// On ajoute les notes de cours (la section apparait uniquement s'il
			// existe une note de cours)
			this.addNoteItem(displayedLesson.getNote());

			// On ajoute les groupes
			if (displayedLesson.getGroups().length() != 0) {
				this.addGroupItem(displayedLesson.getGroups());
			} else {
				String noGroupText = context.getResources()
						.getString(R.string.Lesson_group_unknown);
				this.addGroupItem(noGroupText);
			}// if

			// On ajoute le reste dans la catégorie "plus" : date de création du
			// cours, date de modification du cours
			this.addPlusItem(displayedLesson.getCreated());
		}// bindView(View, Context, Cursor)

		/**
		 * When creating, retrieve this instance's number from its arguments.
		 */
		@Override
		public void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			this.lesson = this.getArguments()
					.getParcelable(FRAGMENT_ARG_LESSON);
		}

		/**
		 * The Fragment's UI is just a simple text view showing its instance id.
		 */
		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			this.mRootView = (ViewGroup) inflater
					.inflate(R.layout.lesson_details_pager_list, null);
			this.mRootView.setBackgroundColor(AdeWebOptions
					.getBackgroundColor(AdeWebOptions.getTheme(this
							.getActivity())));
			return this.mRootView;
		}

		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
			super.onActivityCreated(savedInstanceState);
			LoaderManager manager = this.getLoaderManager();
			if (manager.getLoader(LessonQuery._TOKEN) == null) {
				manager.initLoader(LessonQuery._TOKEN, null, this);
			} else {
				manager.restartLoader(LessonQuery._TOKEN, null, this);
			}// if
		}

		@Override
		public Loader<Cursor> onCreateLoader(int id, Bundle data) {
			Uri lessonUri = ContentUris
					.withAppendedId(AdeWebContract.Lesson.CONTENT_URI,
							this.lesson.lessonId);
			String[] projection = LessonQuery.PROJECTION;
			String selection = null;
			String[] selectionArgs = null;
			return new CursorLoader(this.getActivity(), lessonUri, projection,
					selection, selectionArgs,
					AdeWebContract.Lesson.DEFAULT_SORT);
		}

		@Override
		public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
			if (this.getActivity() == null) {
				return;
			}
			if (cursor.moveToFirst()) {
				bindView(this.getView(), this.getActivity(), cursor);
			} else {
				Log.d(TAG, "Erreur: cours inexistant !"); //$NON-NLS-1$
			}
		}

		@Override
		public void onLoaderReset(Loader<Cursor> loader) {
			/* Nothing to be done. */
		}

		protected interface LessonQuery {
			// id pour le loader
			int _TOKEN = 0x1;

			// Colonnes demandées au provider
			String[] PROJECTION = { BaseColumns._ID,
					AdeWebContract.Lesson.LESSON_CHANGE,
					AdeWebContract.Lesson.LESSON_COLOR,
					AdeWebContract.Lesson.LESSON_CREATED,
					AdeWebContract.Lesson.LESSON_DATE,
					AdeWebContract.Lesson.LESSON_END_TIME,
					AdeWebContract.Lesson.LESSON_GROUPS,
					AdeWebContract.Lesson.LESSON_HISTORY_DATE,
					AdeWebContract.Lesson.LESSON_HISTORY_END_TIME,
					AdeWebContract.Lesson.LESSON_HISTORY_ROOMS,
					AdeWebContract.Lesson.LESSON_HISTORY_START_TIME,
					AdeWebContract.Lesson.LESSON_NOTE,
					AdeWebContract.Lesson.LESSON_ROOMS,
					AdeWebContract.Lesson.LESSON_START_TIME,
					AdeWebContract.Lesson.LESSON_TEACHERS,
					AdeWebContract.Lesson.LESSON_TITLE,
					AdeWebContract.Lesson.LESSON_TYPE,
					AdeWebContract.Lesson.LESSON_SCHEDULE };

			// colonnes des données demandés pour utiliser lors de la
			// récupération
			// des données depuis le Cursor (appels à getString(int) p.ex.)
			int _ID = 0;
			int LESSON_CHANGE = 1;
			int LESSON_COLOR = 2;
			int LESSON_CREATED = 3;
			int LESSON_DATE = 4;
			int LESSON_END_TIME = 5;
			int LESSON_GROUPS = 6;
			int LESSON_HISTORY_DATE = 7;
			int LESSON_HISTORY_END_TIME = 8;
			int LESSON_HISTORY_ROOMS = 9;
			int LESSON_HISTORY_START_TIME = 10;
			int LESSON_NOTE = 11;
			int LESSON_ROOMS = 12;
			int LESSON_START_TIME = 13;
			int LESSON_TEACHERS = 14;
			int LESSON_TITLE = 15;
			int LESSON_TYPE = 16;
			int LESSON_SCHEDULE = 17;
		}

		/**
		 * Ajoute un bandeau de la couleur du cours.
		 * 
		 * @deprecated On colore le header maintenant au lieu d'afficher un
		 *             bandeau supplémentaire.
		 * @param inflater
		 *            layout
		 * @param color
		 *            couleur du cours
		 * @param activated
		 */
		@Deprecated
		public void addColorItem(LayoutInflater inflater, String color,
				boolean activated) {
			ViewGroup colorsContainer = (ViewGroup) this.mRootView
					.findViewById(R.id.lesson_color_block);
			colorsContainer.removeAllViews();

			// Create the color item
			ViewGroup colorContainer = (ViewGroup) inflater
					.inflate(R.layout.lesson_details_bandeau_color,
							colorsContainer,
							false);
			TextView colorView = (TextView) colorContainer
					.findViewById(R.id.color);
			colorView.setBackgroundColor(Color.parseColor(color));

			colorsContainer.addView(colorContainer);
			colorsContainer.setVisibility(activated ? View.VISIBLE : View.GONE);
		}

		/**
		 * Ajoute le champ "Salle" contenant les salles dans lesquelles au lieu
		 * le cours. Chaque salle est affichée sur un item différent.
		 * 
		 * @param inflater
		 *            layout
		 * @param room
		 *            salles (cours courant)
		 * @param oldroom
		 *            salles (historique du cours courant)
		 */
		// TODO Si l'application vennait à être retravailler pour une version
		// API lvl 14 minimum,
		// il serait préférable d'appeller la fonction setVisibility(View.GONE)
		// plutôt que de changer de layout
		public void addRoomItem(LayoutInflater inflater, String room,
				String oldroom) {
			ViewGroup roomsContainer = (ViewGroup) this.mRootView
					.findViewById(R.id.room_container);
			ViewGroup roomContainer;
			TextView title;
			// S'il n'y a pas de changement important de salle, alors on affiche
			// pas de sous-titre
			if (oldroom.equals("")) { //$NON-NLS-1$
				// Create the room item
				roomContainer = (ViewGroup) inflater
						.inflate(R.layout.lesson_details_list_item_room,
								roomsContainer,
								false);
				title = ((TextView) roomContainer.findViewById(R.id.room_text));
				title.setTextAppearance(this.getActivity(),
						R.style.newValueAdded);
			} else if (oldroom.equals(room)) {
				// Create the room item
				roomContainer = (ViewGroup) inflater
						.inflate(R.layout.lesson_details_list_item_room,
								roomsContainer,
								false);
				title = ((TextView) roomContainer.findViewById(R.id.room_text));
			}
			// Sinon on affiche en sous-titre l'ancienne valeur barrée
			else {
				// Create the room item
				roomContainer = (ViewGroup) inflater
						.inflate(R.layout.lesson_details_list_item_room2,
								roomsContainer,
								false);
				TextView subtitle = ((TextView) roomContainer
						.findViewById(R.id.room_subtext));
				subtitle.setText(oldroom);
				subtitle.setPaintFlags(subtitle.getPaintFlags()
						| Paint.STRIKE_THRU_TEXT_FLAG); // on barre le texte
				title = ((TextView) roomContainer.findViewById(R.id.room_text));
			}
			title.setText(room);

			roomContainer.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View view) {
					// TODO Récupère et affiche l'edt de la salle
				}
			});

			roomsContainer.addView(roomContainer);
		}

		/**
		 * Ajoute le champ "Enseignant" contenant les enseignants intervanants
		 * dans le cours. Chaque enseignant est affiché sur un item différent.
		 * 
		 * @param inflater
		 *            layout
		 * @param teacher
		 *            liste d'enseignants
		 */
		public void addTeacherItem(LayoutInflater inflater, String teacher) {
			ViewGroup teachersContainer = (ViewGroup) this.mRootView
					.findViewById(R.id.lesson_teacher_block);

			// Create the teacher item
			View teacherContainer = inflater.inflate(R.layout.teacher_detail,
					teachersContainer,
					false);
			((TextView) teacherContainer.findViewById(R.id.teacher_header))
					.setText(teacher);
			((TextView) teacherContainer.findViewById(R.id.teacher_abstract))
					.setVisibility(View.GONE);
			// ((ImageView)
			// teacherContainer.findViewById(R.id.teacher_image)).setContentDescription(contentDescription);

			teacherContainer.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View view) {
					// TODO Récupère et affiche l'edt de l'enseignant
				}
			});

			teachersContainer.addView(teacherContainer);
		}

		/**
		 * Ajoute le champ "Groupe" contenant les groupes associés au cours.
		 * 
		 * @param group
		 *            groupes
		 */
		public void addGroupItem(String group) {
			ViewGroup groupContainer = (ViewGroup) this.mRootView
					.findViewById(R.id.lesson_group_block);

			// Init the group item
			((TextView) groupContainer.findViewById(R.id.group_text))
					.setText(group);
		}

		/**
		 * Ajoute le champ "Note" contenant la note de cours.
		 * 
		 * @param note
		 *            note de cours
		 */
		public void addNoteItem(String note) {
			ViewGroup noteContainer = (ViewGroup) this.mRootView
					.findViewById(R.id.lesson_note_block);

			// Init the note item
			((TextView) noteContainer.findViewById(R.id.note_text))
					.setText(note);

			noteContainer.setVisibility(TextUtils.isEmpty(note) ? View.GONE
					: View.VISIBLE);
		}

		/**
		 * Ajoute le champ "Initialisement prévu le" contenant la date à
		 * laquelle avait lieu le cours initiallement.
		 * 
		 * @param date
		 *            date du cours
		 */
		public void addInitialDateItem(String dDate, String hDate, String startHour,
				String endHour) {
			ViewGroup initialDateContainer = (ViewGroup) this.mRootView
					.findViewById(R.id.lesson_initial_date_block);

			String date = ""; //$NON-NLS-1$
			if (hDate != null && !hDate.equals(dDate)) {
				date = String.format("%s de %s à %s", //$NON-NLS-1$
						LessonFragment.displayDate(hDate),
						LessonFragment.displayTime(startHour),
						LessonFragment.displayTime(endHour));
			}

			// Init the item
			((TextView) initialDateContainer
					.findViewById(R.id.initial_date_text)).setText(date);

			initialDateContainer
					.setVisibility(!date.equals("") ? View.VISIBLE : View.GONE); //$NON-NLS-1$
		}

		/**
		 * Ajoute le champ "Plus" contenant la date de création du cours.
		 * 
		 * @param createdDate
		 *            date de création
		 */
		public void addPlusItem(String createdDate) {
			ViewGroup plusContainer = (ViewGroup) this.mRootView
					.findViewById(R.id.lesson_plus_block);

			// Init the plus item
			String plus = "Crée le : " + createdDate; //$NON-NLS-1$
			((TextView) plusContainer.findViewById(R.id.plus_text))
					.setText(plus);
		}

		/**
		 * Ordonne l'affichage des salles. Ordre : Salle inchangé, salle
		 * changée, salle supprimée, salle ajoutée.
		 * 
		 * @param inflater
		 *            layout
		 * @param newValues
		 *            liste des salles (cours courant)
		 * @param oldValues
		 *            liste des salles (historique du cours courant)
		 */
		public void initRooms(LayoutInflater inflater, String newValues,
				String oldValues) {
			ArrayList<String> newList = new ArrayList<String>(
					Arrays.asList(parseItems(newValues)));
			ArrayList<String> oldList = new ArrayList<String>(
					Arrays.asList(parseItems(oldValues)));
			ArrayList<String> added = new ArrayList<String>();
			ArrayList<String> removed = new ArrayList<String>();
			ArrayList<String> unchanged = new ArrayList<String>();

			// On tri les 2 listes par ordre alphabétique
			Collections.sort(newList);
			Collections.sort(oldList);

			Iterator<String> oldIter = oldList.iterator();
			Iterator<String> newIter = newList.iterator();
			int i = 0, j = 0, nOld = oldList.size(), nNew = newList.size();
			while ((i < nOld) && (j < nNew)) {
				String oldRoom = oldList.get(i);
				String newRoom = newList.get(j);
				if (oldRoom.equals(newRoom)) {
					unchanged.add(oldRoom);
					i++;
					j++;
				} else if (oldRoom.compareTo(newRoom) < 0) {
					removed.add(oldRoom);
					i++;
				} else /* oldRoom.compareTo(newRoom) > 0 */{
					added.add(newRoom);
					j++;
				}// if
			}// while
			for (; i < nOld; ++i) {
				removed.add(oldList.get(i));
			}// for
			for (; j < nNew; ++j) {
				added.add(newList.get(j));
			}// for

			// on affiche les salles inchangées
			for (String room : unchanged) {
				this.addRoomItem(inflater, room, room);
			}
			// on affiche les salles changées
			int nAdded = added.size();
			int nRemoved = removed.size();

			// Log.d(TAG,
			// String.format("[initRooms]\n  old: %s\n  new: %s\n  added    : %s\n  removed  : %s\n  unchanged: %s\n",
			// oldList, newList, added, removed, unchanged)) ;

			oldIter = removed.iterator();
			newIter = added.iterator();
			if (nAdded < nRemoved) { // Cas : le nbre d'elmts suppr est + grd
										// que le nbre d'elmts ajoutés
				for (int c = 1; c < nAdded; c++) {
					this.addRoomItem(inflater, newIter.next(), oldIter.next());
					newIter.remove();
					oldIter.remove();
				}// for
				this.addRoomItem(inflater,
						newIter.next(),
						TextUtils.join(", ", removed)); //$NON-NLS-1$
			} else { // Cas : le nbre d'elmts ajoutés est + grd que le nbre
						// d'elmts suppr
				for (int c = 0; c < nRemoved; c++) {
					this.addRoomItem(inflater, newIter.next(), oldIter.next());
					newIter.remove();
				}
				// on affiche les salles ajoutées
				for (String room : added) {
					this.addRoomItem(inflater, room, ""); //$NON-NLS-1$
				}
			}
		}

		/**
		 * Parse un {@code String} formaté contenant plusieurs items (séparés
		 * par des virgules) et retourne une liste contenant tous ces éléments.
		 * 
		 * @param s
		 *            {@code String} formatté
		 * 
		 * @return retourne un tableau contenant tous ces éléments.
		 */
		public static String[] parseItems(String s) {
			if (s == null)
				return new String[0];
			String[] g = s.split(","); //$NON-NLS-1$
			if ((g.length == 1) && (g[0].equals(""))) { //$NON-NLS-1$
				g = new String[0];
			}
			return g;
		}// parseItems(String)

		/**
		 * Transforme une {@code String} date de type EEEE/MM/dd en une
		 * {@code String} date de type EEE dd MMM Ex : 2013/01/31 -> Jeu. 31
		 * janv
		 * 
		 * @param date
		 *            date à convertir
		 * @return date convertie
		 */
		public static String displayDate(String date) {
			try {
				SimpleDateFormat dateFormater = new SimpleDateFormat(
						DATE_FORMAT, Locale.FRANCE);
				Date d = LessonList.dateDecoder.parse(date);
				String formattedDate = dateFormater.format(d);
				// Capitalize first letter
				formattedDate = String.format("%S%s", //$NON-NLS-1$
						formattedDate.substring(0, 1),
						formattedDate.substring(1));
				return formattedDate;
			} catch (ParseException e) {
				Log.d(TAG, "Date invalide !", e); //$NON-NLS-1$
			}
			return null;
		}

		/**
		 * Transforme une {@code String} heure de "hh:mm - hh:mm" String} date
		 * de type "hh'h'mm à hh'h'mm". Ex : 14:00-16:00 -> 14h00 à 16h00
		 * 
		 * @param date
		 *            heure à convertir
		 * @return heure convertie
		 */
		public static String displayTime(String date) {
			String heure = date;
			heure = heure.substring(heure.indexOf(" ") + 1); //$NON-NLS-1$
			heure = heure.replace(':', 'h');
			heure = heure.replace('-', 'à');
			return heure;
		}

	}// LessonFragment

	private class myPageChangeListener extends SimpleOnPageChangeListener {
		protected myPageChangeListener() {
			super();
		}

		@Override
		public void onPageSelected(int position) {
			LessonDetails activity = LessonDetails.this;
			activity.getSupportActionBar().setTitle(activity.nameLesson);
			// activity.sendUpdateMessage() ;
		}
	}// class myPageChangeListener
		//
	// /**
	// * {@inheritDoc}
	// * @see fr.ul.ade.prime.ui.AdeWebFragmentActivity#getServiceConnection()
	// */
	// @Override
	// protected ServiceConnection getServiceConnection() {
	// return new ServiceConnectionAdapter(this) ;
	// }// getServiceConnection()
	//
	// private class ServiceConnectionAdapter
	// extends AdeWebFragmentActivity.ServiceConnectionAdapter {
	//
	// /**
	// * {@inheritDoc}
	// */
	// protected ServiceConnectionAdapter(AdeWebFragmentActivity activity) {
	// super(activity) ;
	// }// ServiceConnectionAdapter(AdeWebFragmentActivity)
	//
	// /**
	// * {@inheritDoc}
	// */
	// @Override
	// public void onServiceConnected(ComponentName name, IBinder service) {
	// super.onServiceConnected(name, service) ;
	// // Ajout du sous-titre
	// LessonDetails ld = (LessonDetails) this.activity ;
	// int scheduleId = ld.lessons.get(0).getScheduleId() ;
	// Schedule schedule = null ;
	// try {
	// schedule = ld.serviceApi.getSchedule(scheduleId) ;
	// ld.getSupportActionBar().setSubtitle(schedule.getName()) ;
	// } catch (RemoteException re) {
	// Log.d(TAG, String.format(
	//						"Failed to retrieve schedule width id %d.",  //$NON-NLS-1$
	// Integer.valueOf(scheduleId)), re) ;
	// }// try
	// ld.sendUpdateMessage() ;
	// }// onServiceConnected(ComponentName, IBinder)
	//
	// }// class ServiceConnectionAdapter
	//
	// private class AdeWebServiceListenerAdapter
	// extends AdeWebFragmentActivity.AdeWebServiceListenerAdapter {
	// protected AdeWebServiceListenerAdapter(AdeWebFragmentActivity activity) {
	// super(activity) ;
	// }// AdeWebServiceListenerAdapter(AdeWebFragmentActivity)
	// /**
	// * {@inheritDoc}
	// */
	// @Override
	// protected void handleModifiedLessonTypeRunnable(Lesson modifiedLesson) {
	// LessonDetails ld = (LessonDetails) this.activity ;
	// long modifiedId = modifiedLesson.getLessonId() ;
	// for(Lesson l : ld.lessons) {
	// if (l.getLessonId() == modifiedId) {
	// l.setType(modifiedLesson.getType()) ;
	// break ;
	// }// if
	// }// for
	// ld.mAdapter.notifyDataSetChanged() ;
	// }// handleModifiedLessonTypeRunnable(Lesson)
	//
	// /**
	// * {@inheritDoc}
	// */
	// @Override
	// protected void handleRemovedLessonHistoryRunnable(long lessonId) {
	// LessonDetails ld = (LessonDetails) this.activity ;
	// for(Lesson l : ld.lessons) {
	// if (l.getLessonId() == lessonId) {
	// // Log.d(TAG, "Lesson found and history removed !") ;
	// l.setHistory((LessonHistory) null) ;
	// break ;
	// }// if
	// }// for
	// }// handleRemovedLessonHistoryRunnable(long)
	// }// class AdeWebServiceListenerAdapter
	//
	// private static class UpdateMessageContent {
	// private AdeWebServiceApi serviceApi ;
	// private long lessonId ;
	// /**
	// * @param serviceApi
	// * @param lessonId
	// */
	// public UpdateMessageContent(AdeWebServiceApi serviceApi, long lessonId) {
	// super();
	// this.serviceApi = serviceApi;
	// this.lessonId = lessonId;
	// }
	// /**
	// * @return the serviceApi
	// */
	// public AdeWebServiceApi getServiceApi() {
	// return this.serviceApi;
	// }
	// /**
	// * @return the lessonId
	// */
	// public long getLessonId() {
	// return this.lessonId;
	// }
	// }

}// class LessenDetails
